use super::{EventFd, NullTokenFactory, SReadIdx, SWriteIdx};
use crate::Error;
use hipool::{Allocator, PoolAlloc};

type Pipe<'a, T> = super::pipe::Pipe<'a, T, SWriteIdx, SReadIdx, EventFd>;
pub type Receiver<'a, T, A = PoolAlloc> =
    super::pipe::Receiver<'a, T, NullTokenFactory, Pipe<'a, T>, A>;
pub type Sender<'a, T, A = PoolAlloc> =
    super::pipe::Sender<'a, T, NullTokenFactory, Pipe<'a, T>, A>;
pub type Channel<'a, T, A = PoolAlloc> = (Sender<'a, T, A>, Receiver<'a, T, A>);

pub fn channel<T>(len: usize) -> Result<Channel<'static, T>, Error> {
    channel_in(PoolAlloc, len)
}

pub fn channel_in<'a, T, A>(alloc: A, len: usize) -> Result<Channel<'a, T, A>, Error>
where
    A: Allocator + Clone,
{
    let pipe = Pipe::<'_, T>::new_in(alloc, len)?;
    Ok((Sender::new(pipe.clone()), Receiver::new(pipe.clone())))
}
